package com.luli.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.luli.Utils.ExcelUtil;
import com.luli.Utils.RedisUtils;
import com.luli.Utils.RegisterUtils;
import com.luli.constant.PoiExcelDownloadConstant;
import com.luli.dao.UsersDao;
import com.luli.entity.UserData.UpdateUserParam;
import com.luli.entity.Users;
import com.luli.entity.login.RegisterUser;
import com.luli.entity.login.SysUsers;
import com.luli.entity.poi.ExportExcel;
import com.luli.entity.poi.SheetLocal;
import com.luli.entity.poi.WorkBookLocal;
import com.luli.entity.response.ResponseMsg;
import com.luli.model.PageInfoVo;
import com.luli.service.LoginService;
import com.luli.service.UsersService;
import org.apache.catalina.User;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import static com.luli.Utils.ResponseMsgUtil.getFailMsg;
import static com.luli.Utils.ResponseMsgUtil.getSuccessMsg;
import static com.luli.enumeration.MessageEnum.*;
import java.lang.reflect.Field;
/**
 * 陆离
 * 2022/5/3 1:38:12
 */
@Service
public class UsersServiceImpl implements UsersService {
    @Autowired
    private UsersDao usersDao;

    @Autowired
    private LoginService loginService;

    @Autowired
    private RedisUtils redisUtil;

    @Override
    public List<Users> getUsers(String userName) {
        List<Users> byAccount = usersDao.findByAccount(userName);
        return byAccount;
    }

    @Override
    public ExportExcel downloadExcelGetUsers(String userName) {
        StringBuilder fileName = new StringBuilder();
        List<Object[]> result = Lists.newArrayList();
        fileName.append("用户查询-poi测试");
        WorkBookLocal localWb = new WorkBookLocal(fileName.toString());
        List<Users> byAccount = usersDao.findByAccount(userName);
        for (Users listData : byAccount) {
            result.add(
                    new Object[]{
                            listData.getId(),
                            listData.getName(),
                            listData.getPhone(),
                            listData.getAddress(),
                            listData.getEnrolDate(),
                            listData.getDes()
                    }
            );
        }
        localWb = new WorkBookLocal(fileName.toString());
        localWb
                .getSheets()
                .addAll(
                        Lists.<SheetLocal>newArrayList(
                                new SheetLocal(fileName.toString(), PoiExcelDownloadConstant.USER_DATA_DOW, null, result)));
        return new ExportExcel(localWb);
    }

    @Transactional(readOnly = false, rollbackFor = Exception.class)
    @Override
    public ResponseMsg<?> importExcel(MultipartFile file, String localPath) {
        FileInputStream excelStream = null;
        try {
            String fileName = file.getOriginalFilename();
            File _file = new File(localPath, fileName);
            file.transferTo(_file);
            excelStream = new FileInputStream(localPath + fileName);
            List<List<Object>> excelList = ExcelUtil.readExcel(excelStream);
            //1.文件校验
            if (!fileName.matches("^.+\\.(?i)(xls)$") && !fileName.matches("^.+\\.(?i)(xlsx)$")) {
                return getFailMsg(null, "上传文件格式不正确,请导入xls或者xlsx类型文件", null);
            }
            if (excelList.size() <= 1) {
                return getFailMsg(null, "Excel内容不能为空", null);
            }
            if (excelList.size() > 500001) {
                return getFailMsg(null, "Excel最大数据量50W", null);
            }
            List<Users> listData = new ArrayList<>();
            Users importExcelDataPojo = null;
            for (int i = 0; i < excelList.size(); i++) {
                importExcelDataPojo = new Users();
                for (int j = 0; j < excelList.get(i).size(); j++) {
                    if (i == 0) {
                        switch (j) {
                            case 0:
                                if (null == (excelList.get(i)).get(j)) {
                                    return getFailMsg(null, "第1行" + (j + 1) + "列，标题ID不能为空", null);
                                }
                                break;
                            case 1:
                                if (null == (excelList.get(i)).get(j)) {
                                    return getFailMsg(null, "第1行" + (j + 1) + "列，标题姓名不能为空", null);
                                }
                                break;
                            case 2:
                                if (null == (excelList.get(i)).get(j)) {
                                    return getFailMsg(null, "第1行" + (j + 1) + "列，标题地址不能为空", null);
                                }
                                break;
                            case 3:
                                if (null == (excelList.get(i)).get(j)) {
                                    return getFailMsg(null, "第1行" + (j + 1) + "列，标题日期不能为空", null);
                                }
                                break;
                            case 4:
                                if (null == (excelList.get(i)).get(j)) {
                                    return getFailMsg(null, "第1行" + (j + 1) + "列，标题备注不能为空", null);
                                }
                                break;
                        }
                    } else {
                        switch (j) {
                            case 0:
                                if (null == (excelList.get(i)).get(j)) {
                                    return getFailMsg(null, "第" + (i + 1) + "行" + (j + 1) + "列，ID不能为空", null);
                                } else {
                                    importExcelDataPojo.setId(Integer.valueOf(String.valueOf((excelList.get(i)).get(j))));
                                    listData.add(importExcelDataPojo);
                                    break;
                                }
                            case 1:
                                if (null == (excelList.get(i)).get(j)) {
                                    return getFailMsg(null, "第" + (i + 1) + "行" + (j + 1) + "列，姓名不能为空", null);
                                } else {
                                    importExcelDataPojo.setName((String) (excelList.get(i)).get(j));
                                    listData.add(importExcelDataPojo);
                                    break;
                                }
                            case 2:
                                if (null == (excelList.get(i)).get(j)) {
                                    return getFailMsg(null, "第" + (i + 1) + "行" + (j + 1) + "列，电话不能为空", null);
                                } else {
                                    importExcelDataPojo.setPhone((String) (excelList.get(i)).get(j));
                                    listData.add(importExcelDataPojo);
                                    break;
                                }
                            case 3:
                                if (null == (excelList.get(i)).get(j)) {
                                    return getFailMsg(null, "第" + (i + 1) + "行" + (j + 1) + "列，地址不能为空", null);
                                } else {
                                    importExcelDataPojo.setAddress((String) (excelList.get(i)).get(j));
                                    listData.add(importExcelDataPojo);
                                    break;
                                }
                            case 4:
                                if (null == (excelList.get(i)).get(j)) {
                                    return getFailMsg(null, "第" + (i + 1) + "行" + (j + 1) + "列，日期不能为空", null);
                                } else {
                                    importExcelDataPojo.setEnrolDate(dateToString((Date) (excelList.get(i)).get(j)));
                                    listData.add(importExcelDataPojo);
                                    break;
                                }
                            case 5:
                                if (null == (excelList.get(i)).get(j)) {
                                    return getFailMsg(null, "第" + (i + 1) + "行" + (j + 1) + "列，备注不能为空", null);
                                } else {
                                    importExcelDataPojo.setDes((String) (excelList.get(i)).get(j));
                                    listData.add(importExcelDataPojo);
                                    break;
                                }

                        }
                    }
                }
            }
            List<Users> collectData = listData.parallelStream().distinct().collect(Collectors.toList());
            System.out.println(collectData);
            usersDao.addData(collectData);
            return getSuccessMsg(null, "导入成功", null);
        } catch (Exception e) {
            e.printStackTrace();
            return getFailMsg(null, "导入失败", null);
        } finally {
            try {
                excelStream.close();
            } catch (IOException ioException) {
                ioException.printStackTrace();
            }
        }
    }


    @Override
    public SysUsers findUser(String account, String password) {
        SysUsers user = usersDao.findUser(account, password);
        return user;
    }


    @Override
    @Transactional
    public Boolean insertUser(RegisterUser userInfo) {
        usersDao.insertUser(userInfo);
        SysUsers user = usersDao.findUser(userInfo.getAccount(), userInfo.getPassWord());
        if (user == null) {
            return false;
        } else {
            return true;
        }
    }

    @Override
    public PageInfo<Users> getUsersPageTest(String userName, Integer pageNum, Integer pageSize, String sex) {
        PageInfoVo pageInfoVo = new PageInfoVo();
        if (pageNum != null) {
            pageInfoVo.setPageNum(pageNum);
        }
        if (pageSize != null) {
            pageInfoVo.setPageSize(pageSize);
        }
        PageHelper.startPage(pageInfoVo.getPageNum(), pageInfoVo.getPageSize());
        List<Users> byAccount = usersDao.findByUserAndSex(userName, sex);
        PageInfo<Users> pageInfo = new PageInfo(byAccount);
        return pageInfo;
    }


    @Override
    public ResponseMsg<?> delUser(String account) {
        //判断用户是否存在
        String userById = usersDao.findUserById(account);
        if ("0".equals(userById)) {
            return getFailMsg(ACCOUNT_ISNULL.getCode(), ACCOUNT_ISNULL.getMsg(), null);
        } else {
            usersDao.delUserById(account);
        }
        return getSuccessMsg(DEL_USER_SUCCESS.getCode(), DEL_USER_SUCCESS.getMsg(), account + "用户删除成功");
    }


    @Override
    public ResponseMsg<?> updateUser(UpdateUserParam updateUserParam) {
        //判断所修改用户是否存在
        String userById = usersDao.findUserById(updateUserParam.getAccount());
        if (!"0".equals(userById)) {
            //校验参数
            ResponseMsg<?> responseMsg = RegisterUtils.checkUpdateUser(updateUserParam);
            //修改
            if ("1004".equals(responseMsg.getHead().getRequestId())) {
                Object params = responseMsg.getData();
                ObjectMapper objectMapper = new ObjectMapper();
                // 实体类对象接收
                UpdateUserParam userParam = objectMapper.convertValue(params, UpdateUserParam.class);
                System.out.println(userParam);
                int updateUserNum = usersDao.updateUser(userParam);
                return getSuccessMsg(UPDATE_USER_SUCCESS.getCode(), UPDATE_USER_SUCCESS.getMsg(), "成功修改：" + updateUserNum + "条数据");
            } else {
                return responseMsg;
            }

        }
        return getFailMsg(USER_ISNULL.getCode(), USER_ISNULL.getMsg(), null);
    }


    @Override
    public ExportExcel downloadExcelUsers(String userName) {
        StringBuilder fileName = new StringBuilder();
        List<Object[]> result = Lists.newArrayList();
        fileName.append("用户信息");
        WorkBookLocal localWb = new WorkBookLocal(fileName.toString());
        List<Users> byAccount = usersDao.findByAccount(userName);
        for (Users listData : byAccount) {
            result.add(
                    new Object[]{
                            listData.getAccount(),
                            listData.getName(),
                            listData.getAddress(),
                            listData.getSex(),
                            listData.getUserGrade(),
                            listData.getPhone(),
                            listData.getDes(),
                            listData.getEmail(),
                            listData.getAge()
                    }
            );
        }
        localWb = new WorkBookLocal(fileName.toString());
        localWb
                .getSheets()
                .addAll(
                        Lists.<SheetLocal>newArrayList(
                                new SheetLocal(fileName.toString(), PoiExcelDownloadConstant.USER_DATA, null, result)));
        return new ExportExcel(localWb);
    }


    public ExportExcel downloadExcelGetUsersSheets(String userName) {
        StringBuilder fileName = new StringBuilder();
        List<Object[]> result = Lists.newArrayList();
        fileName.append("用户信息");
        WorkBookLocal localWb = new WorkBookLocal(fileName.toString());
        List<Users> byAccount = usersDao.findByAccount(userName);
        for (Users listData : byAccount) {
            result.add(
                    new Object[]{
                            listData.getAccount(),
                            listData.getName(),
                            listData.getAddress(),
                            listData.getSex(),
                            listData.getUserGrade(),
                            listData.getPhone(),
                            listData.getDes(),
                            listData.getEmail(),
                            listData.getAge()
                    }
            );
        }
        localWb = new WorkBookLocal(fileName.toString());
        localWb
                .getSheets()
                .addAll(
                        Lists.<SheetLocal>newArrayList(
                                new SheetLocal(fileName.toString(), PoiExcelDownloadConstant.USER_DATA, null, result),
                                new SheetLocal("test2", PoiExcelDownloadConstant.USER_DATA, null, result)));
        return new ExportExcel(localWb);
    }

    private static String dateToString(Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String strTime = sdf.format(date);
        return strTime;
    }

    private static String dateToString(Date date, String dateCode) {
        SimpleDateFormat sdf = new SimpleDateFormat(dateCode);
        String strTime = sdf.format(date);
        return strTime;
    }




    @Override
//    @Transactional(rollbackFor = Exception.class)
    public void updateUserService(String age, String account) {

        try {
            UpdateUserParam updateUserParam = new UpdateUserParam();
            updateUserParam.setAccount(account);
            updateUserParam.setAge(age);
            int updateUserNum = usersDao.updateUser(updateUserParam);
            delUserService(account);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delUserService(String account) {
        usersDao.delUserById(account);
        int a = 10 / 0;
    }

    public static void main(String[] args) throws NoSuchFieldException {
        Integer state = null;
        if( state != null && state == 6){
            System.out.println(1111);
        }else {
            System.out.println(2222);
        }

    }
}
